/*
 * This file is part of Sparwe.
 *
 *  Sparwe is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Sparwe is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Sparwe.  If not, see <http://www.gnu.org/licenses/>.
 */ 


#ifndef __STRINGTOPRIMITIVE_H__
#define __STRINGTOPRIMITIVE_H__

#include <boost/lexical_cast.hpp>
#include <exception>
#include <string>

#include "../exceptions.h"

#define EXCEPTION_STRING "Could not cast from string to primitive data type."

namespace sp_policies
{
	template <class T>
	class StringToString : public T
	{
		public:

		
			/** 
			 * @brief Converts an string to... string... sounds stupid but it is just for consistency matters. :p 
			 * 
			 * @param in 
			 * 
			 * @return 
			 */
			std::string Convert(std::string in) const
			{
				return in;
			}
	};

	template <class T>
	class StringToInt : public T
	{
		public:
			/** 
			 * @brief Converts a string to int.
			 * 
			 * @param in 
			 * 
			 * @return 
			 */
			int Convert(std::string in) const throw()
			{
				int num;
				try
				{
					num = boost::lexical_cast<int>(in);					
				}
				catch ( boost::bad_lexical_cast &)
				{
					throw new sp_core::BadCastException(EXCEPTION_STRING);
				}

				return num;
			}

	};

	template <class T>
	class StringToFloat : public T
	{
		public:
			/** 
			 * @brief Converts a string to float.
			 * 
			 * @param in 
			 * 
			 * @return 
			 */
			float Convert(std::string in) const
			{
				float num;

				try
				{
					num = boost::lexical_cast<float>(in);
				}
				catch ( boost::bad_lexical_cast & )
				{
					throw new sp_core::BadCastException(EXCEPTION_STRING);
				}
				
				return num;
			}

	};

	template <class T>
	class StringToDouble : public T
	{
		public:
			/** 
			 * @brief Converts a string to double.
			 * 
			 * @param in 
			 * 
			 * @return 
			 */
			double Convert(std::string in) const
			{
				double num;

				try 
				{
					num = boost::lexical_cast<double>(in);
				}
				catch ( boost::bad_lexical_cast & )
				{
					throw new sp_core::BadCastException(EXCEPTION_STRING);
				}

				return num;
			}


			
	};

	template <class T>
	class StringToBool : public T
	{
		public:
			/** 
			 * @brief Converts a string to bool
			 * 
			 * @param in 
			 * 
			 * @return 
			 */
			bool Convert(std::string in) const
			{
				// FIXME Make this to work with boost instead of the current hack!
				
				bool eval; 
				
				if (in.compare("true") == 0)
					return true;
				else if (in.compare("false") == 0)
					return false;
				else
					throw new sp_core::BadCastException(EXCEPTION_STRING);

			}

	};	


}



#endif
